home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
yerk
/
mps231ss.hqx
/
Mops source
/
More classes
/
MW documents
/
Info_run
< prev
next >
Wrap
Text File
|
1990-11-15
|
4KB
|
138 lines
\ The info_run class is used to implement fmt_run and para_run.
\ An info_run consists of a set of items, each of which starts with a
\ 4-byte offset (aligned) followed by a number of bytes of information.
\ This particular number is fixed for each object of this class, but
\ may vary between objects. It must be even, though.
0 value STRT \ Used in FIXUP: and MOVE: because we can
\ only have 5 locals!
:class (INFO_RUN) super( bytestring )
int INFOSIZE
:m INFOSIZE: get: infoSize ;m
:m ITEMSIZE: get: infoSize 4+ ;m
:m SETINFOSIZE: put: infoSize ;m
:m SKIP_INFO: get: infoSize skip: self ;m
:m SKIP_ITEM: get: infoSize 4+ skip: self ;m
:m <SKIP_INFO: get: infoSize negate skip: self ;m
:m <SKIP_ITEM: get: infoSize 4+ negate skip: self ;m
:m OFFS: ^1st: self @ ;m
:m NEW_ITEM: { offs -- } \ Sets up a new item - all zero initially.
\ Leaves POS at the info field.
pad itemSize: self 2dup erase offs pad !
pos: self 0dup
IF
^1st: self itemSize: self - @ offs =
THEN
IF ( same offset as previous entry - overwrite prev entry )
<skip_item: self ovwr: self
ELSE
insert: self
THEN
<skip_info: self ;m
:m FIND_POSN: { offs reset? -- }
reset? IF reset: self THEN
BEGIN
len: self 0EXIT
^1st: self @ offs > ?EXIT
skip_item: self
AGAIN ;m
:m FIXUP: { offs oldlen newlen \ nxt n -- }
\ Makes the necessary adjustments when some text being pointed to by this
\ info_run is about to be replaced. To save time, we assume that SELF only
\ has to be scanned from its current position. Remember to RESET: it if
\ there's any doubt.
pos: self -> strt newlen oldlen - -> n
nolim: self
BEGIN \ loop to get up to the place where we have to do anything
len: self NIF strt >pos: self EXIT THEN
nxtL: self -> nxt offs nxt >
WHILE
skip_info: self
REPEAT
BEGIN \ loop to coerce any changes within the old string
\ to go to the right of the new string
nxt offs - oldlen <
WHILE
newlen offs + -4 skip: self >nxtL: self
skip_info: self
len: self NIF strt >pos: self EXIT THEN
nxtL: self -> nxt
REPEAT
BEGIN \ loop to adjust the rest of the offsets
nxt n + -4 skip: self >nxtL: self
skip_info: self
len: self NIF strt >pos: self EXIT THEN
nxtL: self -> nxt
AGAIN ;m
;class
(info_run) TEMP
objPtr TheIR \ Class will be set to info_run
:class INFO_RUN super( (info_run) )
' theIR set_to_class info_run
:m MOVE: { pos len trg \ end dist -- }
\ Sets up Self for when some text is to be moved. The text is delimited
\ by pos and len in the text string, and will be moved to the offset trg.
new: temp infosize: self setinfosize: temp
pos 1- true find_posn: self pos: self -> strt
pos len + false find_posn: self pos: self -> end
strt >pos: self end >lim: self
^base ->: temp delete: self nolim: self
pos len 0 fixup: self
len --> trg
trg false find_posn: self
trg 0 len fixup: self \ For insert
trg pos - -> dist
BEGIN
len: temp
WHILE
dist ^1st: temp +!
skip_item: temp
REPEAT
reset: temp temp $insert: self
\ reset: temp len: temp
\ IF
\ nxtL: temp new_item: self
\ \ We don't just insert as prev item may have same offset
\ temp $ovwr: self
\ THEN
reset: self release: temp ;m
:m CUT: { pos len IRobj \ strt end -- }
IRobj -> theIR
infosize: theIR setinfosize: self
pos 1- true find_posn: theIR pos: theIR -> strt
pos len + false find_posn: theIR pos: theIR -> end
strt >pos: theIR end >lim: theIR
theIR ->: self delete: theIR reset: self nolim: theIR
pos len 0 fixup: theIR
0 pos 0 fixup: self ;m
:m PASTE: { pos len IRobj -- }
IRobj -> theIR reset: theIR
pos true find_posn: self
pos 0 len fixup: self \ For insert
0 0 pos fixup: theIR
reset: theIR theIR $insert: self
reset: self ;m
;class